<template>
  <div class="passmanage">
    <el-form ref="formRef" :label-width="70" :model="ruleForm" :rules="rules" status-icon>
      <el-form-item label="原密码" prop="oldPass">
        <el-input
          ref="oldPassRef"
          type="password"
          :disabled="isLoading"
          v-model="ruleForm.oldPass"
          placeholder="请输入原密码"
          @keyup.enter.prevent="focus('newPassRef')"
          :maxlength="10"
        />
        <SvgIcon popper-class="input-icon" icon-class="lock" />
      </el-form-item>
      <el-form-item label="新密码" prop="newPass">
        <el-input
          ref="newPassRef"
          type="password"
          :disabled="isLoading"
          v-model="ruleForm.newPass"
          placeholder="请输入新密码"
          @keyup.enter.prevent="focus('checkPassRef')"
          :maxlength="10"
        />
        <SvgIcon popper-class="input-icon" icon-class="lock" />
      </el-form-item>
      <el-form-item label="重复密码" prop="checkPass">
        <el-input
          ref="checkPassRef"
          type="password"
          :disabled="isLoading"
          v-model="ruleForm.checkPass"
          placeholder="请再一次输入新密码"
          :maxlength="10"
          @keyup.enter.prevent="submitForm(formRef)"
        />
        <SvgIcon popper-class="input-icon" icon-class="locked" />
      </el-form-item>
    </el-form>
    <div class="submit-pass">
      <el-button
        class="submit-pass__button"
        type="primary"
        :loading="isLoading"
        :disabled="isLoading"
        @click="submitForm(formRef)"
        ><template #loading><Loading /></template>确认</el-button
      >
    </div>
  </div>
</template>

<script lang="ts">
export default defineComponent({
  methods: {
    // 输入框聚焦
    focus(refValue: string): void {
      (this.$refs as any)[refValue].focus();
    },
  },
});
</script>

<script lang="ts" setup>
import { ref, reactive, defineComponent } from "vue";
import type { FormInstance, ElInput } from "element-plus";
import { Base64 } from "js-base64";
import { ElMessage } from "element-plus";
import axios from "axios";

/**
 * 表单内的属性值
 */
const ruleForm = reactive<{
  oldPass: string;
  newPass: string;
  checkPass: string;
}>({
  oldPass: "",
  newPass: "",
  checkPass: "",
});

/**
 * 给el-form标签一个ref属性
 */
const formRef = ref<FormInstance>();

// 表单的验证
const validateInput = (
  title: string,
  count?: number
): ((rule: any, value: string, callback: any) => void) => (
  rule: any,
  value: string,
  callback: any
): void => {
  if (!value) callback(new Error("密码不能为空"));
  else if (!value.match(/^[a-zA-Z0-9_\\.]{1,}$/g) && title !== "旧密码")
    callback(new Error("密码只能由字母、数字、小数点和下划线组成"));
  else if (count && value.length < count)
    callback(new Error(`密码长度不能少于${count}位`));
  else {
    let isRight: boolean = true;
    if (title === "新密码" && ruleForm.checkPass && formRef.value)
      formRef.value.validateField("checkPass");
    if (title === "重复密码" && value !== ruleForm.newPass) {
      callback(new Error("两次密码输入不一致"));
      isRight = false;
    }
    if (isRight) callback();
  }
};
/**
 * 表单校验规则
 */
const rules = reactive({
  oldPass: [{ validator: validateInput("旧密码", 10), trigger: "blur" }],
  newPass: [{ validator: validateInput("新密码", 10), trigger: "blur" }],
  checkPass: [{ validator: validateInput("重复密码", 10), trigger: "blur" }],
});

/**
 * 重置该表单项，将其值重置为初始值，并移除校验结果
 */
const resetFields = () => formRef.value?.resetFields();

defineExpose({
  resetFields,
});

/**
 * 清空表单值
 */
const clearForm = () => {
  ruleForm.oldPass = "";
  ruleForm.newPass = "";
  ruleForm.checkPass = "";
};

/**
 * 给旧密码框一个ref属性
 */
const oldPassRef = ref<typeof ElInput>();
/**
 * 是否正在修改密码
 */
const isLoading = ref<boolean>(false);
// 提交并开始修改密码
const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      isLoading.value = true;
      axios
        .post("/api/user/updatePass", {
          data: Base64.encode(
            JSON.stringify({
              oldPass: ruleForm.oldPass,
              newPass: ruleForm.newPass,
            })
          ),
        })
        .then(({ data }) => {
          isLoading.value = false;
          if (data.code === 1) {
            clearForm();
            ElMessage({
              type: "success",
              message: "修改成功",
              duration: 1500,
            });
          } else
            ElMessage({
              type: "error",
              message: data.msg,
              duration: 1500,
            });
          oldPassRef.value?.focus();
        })
        .catch(() => {
          isLoading.value = false;
          ElMessage({
            type: "error",
            message: "修改失败",
            duration: 1500,
          });
          oldPassRef.value?.focus();
        });
    }
  });
};
</script>

<style lang="scss" scoped>
.passmanage {
  width: 75%;
  margin: 0 30px;

  :deep(.el-form-item) {
    margin-bottom: 23px;
  }

  :deep(.el-input__inner) {
    padding-left: 28px;
  }

  .submit-pass {
    margin: 30px 0;
    text-align: center;

    &__button {
      width: 90%;
    }
  }
}
</style>
